Calc's “pack” and “unpack” commands collect stack entries to build composite objects such as vectors and complex numbers. They are described in this chapter because they are most often used to build vectors.
The
v p (calc-pack) [pack]
command collects several elements from the stack into a matrix,
complex number, HMS form, error form, etc. It uses a numeric
prefix argument to specify the kind of object to be built; this
argument is referred to as the “packing mode.” If the
packing mode is a nonnegative integer, a vector of that length is
created. For example, C-u 5 v p will pop the top five
stack elements and push back a single vector of those five
elements. (C-u 0 v p simply creates an empty
vector.)
The same effect can be had by pressing [ to push an
incomplete vector on the stack, using <TAB>
(calc-roll-down) to sneak the incomplete object up
past a certain number of elements, and then pressing ]
to complete the vector.
Negative packing modes create other kinds of composite objects:
With any of the two-input negative packing modes, either or both of the inputs may be vectors. If both are vectors of the same length, the result is another vector made by packing corresponding elements of the input vectors. If one input is a vector and the other is a plain number, the number is packed along with each vector element to produce a new vector. For example, C-u -4 v p could be used to convert a vector of numbers and a vector of errors into a single vector of error forms; C-u -5 v p could convert a vector of numbers and a single number M into a vector of numbers modulo M.
If you don't give a prefix argument to v p, it takes the packing mode from the top of the stack. The elements to be packed then begin at stack level 2. Thus 1 <RET> 2 <RET> 4 n v p is another way to enter the error form ‘1 +/- 2’.
If the packing mode taken from the stack is a vector, the result is a matrix with the dimensions specified by the elements of the vector, which must each be integers. For example, if the packing mode is ‘[2, 3]’, then six numbers will be taken from the stack and returned in the form ‘[[a, b, c], [d, e, f]]’.
If any elements of the vector are negative, other kinds of packing are done at that level as described above. For example, ‘[2, 3, -4]’ takes 12 objects and creates a 2x3 matrix of error forms: ‘[[a +/- b, c +/- d ... ]]’. Also, ‘[-4, -10]’ will convert four integers into an error form consisting of two fractions: ‘a:b +/- c:d’.
There is an equivalent algebraic function, ‘pack(mode, items)’ where mode is a packing mode (an integer or a vector of integers) and items is a vector of objects to be packed (re-packed, really) according to that mode. For example, ‘pack([3, -4], [a,b,c,d,e,f])’ yields ‘[a +/- b, c +/- d , e +/- f]’. The function is left in symbolic form if the packing mode is invalid, or if the number of data items does not match the number of items required by the mode.
The v u
(calc-unpack) command takes the vector, complex
number, HMS form, or other composite object on the top of the
stack and “unpacks” it, pushing each of its elements
onto the stack as separate objects. Thus, it is the
“inverse” of v p. If the value at the top
of the stack is a formula, v u unpacks it by pushing
each of the arguments of the top-level operator onto the
stack.
You can optionally give a numeric prefix argument to v u to specify an explicit (un)packing mode. If the packing mode is negative and the input is actually a vector or matrix, the result will be two or more similar vectors or matrices of the elements. For example, given the vector ‘[a +/- b, c^2, d +/- 7]’, the result of C-u -4 v u will be the two vectors ‘[a, c^2, d]’ and ‘[b, 0, 7]’.
Note that the prefix argument can have an effect even when the input is not a vector. For example, if the input is the number -5, then c-u -1 v u yields -5 and 0 (the components of -5 when viewed as a rectangular complex number); C-u -2 v u yields 5 and 180 (assuming Degrees mode); and C-u -10 v u yields -5 and 1 (the numerator and denominator of -5, viewed as a rational number). Plain v u with this input would complain that the input is not a composite object.
Unpacking mode -11 converts a float into an integer mantissa and an integer exponent, where the mantissa is not divisible by 10 (except that 0.0 is represented by a mantissa and exponent of 0). Unpacking mode -12 converts a float into a floating-point mantissa and integer exponent, where the mantissa (for non-zero numbers) is guaranteed to lie in the range [1 .. 10). In both cases, the mantissa is shifted left or right (and the exponent adjusted to compensate) in order to satisfy these constraints.
Positive unpacking modes are treated differently than for v p. A mode of 1 is much like plain v u with no prefix argument, except that in addition to the components of the input object, a suitable packing mode to re-pack the object is also pushed. Thus, C-u 1 v u followed by v p will re-build the original object.
A mode of 2 unpacks two levels of the object; the resulting re-packing mode will be a vector of length 2. This might be used to unpack a matrix, say, or a vector of error forms. Higher unpacking modes unpack the input even more deeply.
There are two algebraic functions analogous to v u. The ‘unpack(mode, item)’ function unpacks the item using the given mode, returning the result as a vector of components. Here the mode must be an integer, not a vector. For example, ‘unpack(-4, a +/- b)’ returns ‘[a, b]’, as does ‘unpack(1, a +/- b)’.
The
unpackt function is like unpack but
instead of returning a simple vector of items, it returns a
vector of two things: The mode, and the vector of items. For
example, ‘unpackt(1, 2:3 +/-
1:4)’ returns ‘[-4, [2:3, 1:4]]’, and
‘unpackt(2, 2:3 +/-
1:4)’ returns ‘[[-4, -10], [2, 3, 1, 4]]’. The
identity for re-building the original object is
‘apply(pack,
unpackt(n,
x)) =
x’. (The apply function
builds a function call given the function name and a vector of
arguments.)
Subscript notation is a useful way to extract a particular part of an object. For example, to get the numerator of a rational number, you can use ‘unpack(-10, x)_1’.